﻿using System;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media.Animation;

namespace Emilie.Animation
{
    public static class TargetProperty
    {
        // Render Transform Composite Transform X-Axis Translation
        public static String RenderTransformTranslateX = "(UIElement.RenderTransform).(CompositeTransform.TranslateX)";
        // Render Transform Composite Transform Y-Axis Translation
        public static String RenderTransformTranslateY = "(UIElement.RenderTransform).(CompositeTransform.TranslateY)";
        // Render Transform Composite Transform X-Axis Scale
        public static String RenderTransformScaleX = "(UIElement.RenderTransform).(CompositeTransform.ScaleX)";
        // Render Transform Composite Transform Y-Axis Scale
        public static String RenderTransformScaleY = "(UIElement.RenderTransform).(CompositeTransform.ScaleY)";
        // Render Transform Composite Transform X-Scale Skew
        public static String RenderTransformSkewX = "(UIElement.RenderTransform).(CompositeTransform.SkewX)";
        // Render Transform Composite Transform Y-Scale Skew
        public static String RenderTransformSkewY = "(UIElement.RenderTransform).(CompositeTransform.SkewY)";
        // Render Transform Composite Transform Rotation
        public static String RenderTransformRotation = "(UIElement.RenderTransform).(CompositeTransform.Rotation)";
        // UIElement Opacity
        public static String Opacity = "(UIElement.Opacity)";
        // UIElement Visibility
        public static String Visiblity = "(UIElement.Visibility)";
        // Plane Projection X-Axis Rotation
        public static String ProjectionRotationX = "(UIElement.Projection).(PlaneProjection.RotationX)";
        // Plane Projection Y-Axis Rotation
        public static String ProjectionRotationY = "(UIElement.Projection).(PlaneProjection.RotationY)";
        // Plane Projection Z-Axis Rotation
        public static String ProjectionRotationZ = "(UIElement.Projection).(PlaneProjection.RotationZ)";
        public static String ProjectionGlobalOffsetX = "(UIElement.Projection).(PlaneProjection.GlobalOffsetX)";
        public static String ProjectionGlobalOffsetY = "(UIElement.Projection).(PlaneProjection.GlobalOffsetY)";
        public static String ProjectionGlobalOffsetZ = "(UIElement.Projection).(PlaneProjection.GlobalOffsetZ)";
        public static String ShapeFillSolidColorBrushColor = "(Shape.Fill).(SolidColorBrush.Color)";
    }

    /// <summary>
    /// A set of extension methods to make working with Storyboards easier
    /// </summary>
    public static class Keyframes
    {
        /// <summary>
        /// Ensures an element has a CompositeTransform for RenderTransform operations, or a PlaneProjection for Projection operations
        /// </summary>
        /// <param name="target">Element to animate</param>
        /// <param name="targetProperty">And property path string of the property to animate</param>
        public static void EnsurePlumbing(FrameworkElement target, String targetProperty)
        {
            if (targetProperty == TargetProperty.RenderTransformRotation || targetProperty == TargetProperty.RenderTransformScaleX
                || targetProperty == TargetProperty.RenderTransformScaleY || targetProperty == TargetProperty.RenderTransformSkewX || targetProperty == TargetProperty.RenderTransformSkewY
                || targetProperty == TargetProperty.RenderTransformTranslateX || targetProperty == TargetProperty.RenderTransformTranslateY)
                target.GetCompositeTransform();
            else if (targetProperty == TargetProperty.ProjectionGlobalOffsetX || targetProperty == TargetProperty.ProjectionGlobalOffsetY || targetProperty == TargetProperty.ProjectionGlobalOffsetZ
                || targetProperty == TargetProperty.ProjectionRotationX || targetProperty == TargetProperty.ProjectionRotationY || targetProperty == TargetProperty.ProjectionRotationZ)
                target.GetPlaneProjection();
        }

        public static void AddTimeline(this Storyboard storyboard, Timeline timeline, FrameworkElement target,  String targetProperty)
        {
            EnsurePlumbing(target, targetProperty);

            Storyboard.SetTarget(timeline, target);
            Storyboard.SetTargetName(timeline, target.Name);
            Storyboard.SetTargetProperty(timeline, targetProperty);

            storyboard.Children.Add(timeline);
        }

        public static void AddEasingDoubleKeyFrame(this DoubleAnimationUsingKeyFrames doubleAnimation, TimeSpan time, double value, EasingFunctionBase ease = null)
        {
            doubleAnimation.KeyFrames.Add(new EasingDoubleKeyFrame
            {
                KeyTime = KeyTime.FromTimeSpan(time),
                Value = value,
                EasingFunction = ease
            });
        }

        public static void AddEasingColorKeyFrame(this ColorAnimationUsingKeyFrames colorAnimation, TimeSpan time, Color value, EasingFunctionBase ease = null)
        {
            colorAnimation.KeyFrames.Add(new EasingColorKeyFrame
            {
                KeyTime = KeyTime.FromTimeSpan(time),
                Value = value,
                EasingFunction = ease
            });
        }

        public static void AddSplineDoubleKeyFrame(this DoubleAnimationUsingKeyFrames doubleAnimation, TimeSpan time, double value, KeySpline spline = null)
        {
            doubleAnimation.KeyFrames.Add(new SplineDoubleKeyFrame
            {
                KeyTime = KeyTime.FromTimeSpan(time),
                Value = value,
                KeySpline = spline
            });
        }

        public static void AddDiscreteObjectKeyFrame(this ObjectAnimationUsingKeyFrames objectAnimation, TimeSpan time, object value)
        {
            objectAnimation.KeyFrames.Add(new DiscreteObjectKeyFrame
            {
                KeyTime = KeyTime.FromTimeSpan(time),
                Value = value
            });
        }
        
    }
}
